package au.com.langdale.gwt.client.model;


import com.google.gwt.user.client.rpc.IsSerializable;

/**
 * A ModelInfo instance provides the metadata, accessors and validation
 * for a class of model objects. It is used in situations where the objects' 
 * type is not known at compile time and no java reflection is available
 * at runtime. This is the situation in some GWT user interface code.<p>
 * 
 * Each derivative of ModelInfo must provide the name of the class
 * it describes and an array of Property objects for that class. (See 
 * Property.)  It may also provide validation.<p>  
 * 
 * As a ModelInfo does not contain or wrap the instance, the metadata 
 * can be used when no instance is available.  A ModelInfo is usually
 * a stateless singleton.<p> 
 * 
 * A set of hibernate templates is provided that generate concrete
 * ModelInfo classes, and a singleton instance of each, for database 
 * tables.<p>
 *  
 * @author adv
 *
 */
public abstract class ModelInfo implements IsSerializable {
	
	public ModelInfo() {
		// make it serializable
	}

	public abstract String getName();
	public abstract Property[] getProperties();
	public abstract Property[] getKeyProperties();
	
	public String getLabel() {
		return getName();
	}
		
	public String validate(Object model) {
		Property props[][] = new Property[][] {
				getKeyProperties(), 
				getProperties()
		};
		
		for( int  ix = 0; ix < props.length; ++ix) {
			for( int iy = 0; iy < props[ix].length; ++iy) {
				String message = props[ix][iy].validate(model);
				if( message != null)
					return message;
			}
		}
		return null;
	}
}
